package alejandro.celulares

import java.sql.Time
import java.sql.Date
import scala.collection.mutable.ListBuffer

trait Duplicable[T <: Duplicable[T]]{
  def duplicate(): T
}

object Comunicacion {
   def joinComunicaciones(
    		msjtxt:ListBuffer[MensajeDeTexto],
    		llamLc:ListBuffer[LlamadaLocal],
    		llamLg:ListBuffer[LlamadaLarga]
			) : ListBuffer[Comunicacion] = {        
    	var comunicaciones = new ListBuffer[Comunicacion]()
    	comunicaciones appendAll(msjtxt)
    	comunicaciones appendAll(llamLc)
    	comunicaciones appendAll(llamLg)      
    	comunicaciones
	}
}

abstract class Comunicacion (numeroDestinoP: Long, fechaP: Date){
    
    var numeroDestino: Long = numeroDestinoP
    var fecha: Date = fechaP
    var precioConDescuento: BigDecimal = null
	def getNumeroDestino(): Long = numeroDestino
	def setNumeroDestino(destinoP: Long) = {
	    numeroDestino = destinoP
	}
	def getFecha(): Date = fecha
	def setFecha(fechaP: Date) = {
	    fecha = fechaP
	}
	def getPrecioConDescuento(): BigDecimal = precioConDescuento
	def setPrecioConDescuento(precioConDescuentoP: BigDecimal) = {
	    precioConDescuento = precioConDescuentoP
	}
	def generarPrecioConDescuento(): this.type = {
	    precioConDescuento = precioComunicacion()
	    this
	}
	def anularPrecioConDescuento(): BigDecimal = {
	    precioConDescuento = null
	    precioConDescuento
	}
	def esMesYAnio(mes: Integer, anio: Integer): Boolean = {
	  getFecha().getMonth().equals(mes) & getFecha().getYear().equals(anio)
	}
		
    def precioComunicacion(): BigDecimal
    def esComunicacionLarga(): Boolean

}

class LlamadaLocal (numeroDestinoP: Long, duracionP: Time, fechaP: Date)
  extends Comunicacion(numeroDestinoP, fechaP) with Duplicable[LlamadaLocal]{	
    val PRECIOMINUTO: BigDecimal = 0.5
    var duracion: Time = duracionP    
	def getDuracion(): Time = duracion	
	def setDuracion(duracionP: Time) = {
	    duracion = duracionP
	}
    
    def cantMinutos() : Integer = {
    (duracion.getHours()*60 + duracion.getMinutes() + (if (duracion.getSeconds() > 0 ) 1 else 0))
    }
    
    override def precioComunicacion() : BigDecimal = {
        PRECIOMINUTO * BigDecimal.int2bigDecimal(cantMinutos())
    }
    
    override def esComunicacionLarga(): Boolean = {
        (duracion.getMinutes()>5) | (duracion.getMinutes()==5 & duracion.getSeconds()>0)
    }    
    
    override def duplicate(): LlamadaLocal = {
        new LlamadaLocal(numeroDestino, duracion, fecha)
    }
}

class LlamadaLarga (numeroDestinoP: Long, duracionP: Time, locOrigenP: Localidad, locDestinoP: Localidad, fechaP: Date) 
  extends LlamadaLocal(numeroDestinoP, duracionP, fechaP){	
    var locOrigen: Localidad = locOrigenP	
    var locDestino: Localidad = locDestinoP 
    
    
	def getLocOrigen(): Localidad = locOrigen	
	def setLocOrigen(locOrigenP: Localidad) = {
	    locOrigen = locOrigenP
	}   
    def getLocDestino(): Localidad = locDestino	
	def setLocDestino(locDestinoP: Localidad) = {
	    locDestino = locDestinoP
	}
    
    override def precioComunicacion() : BigDecimal = {
        cantMinutos * (locOrigen precioHasta locDestino) 
    }
    
    override def duplicate():LlamadaLarga = {
        new LlamadaLarga(numeroDestino, duracion,locOrigen, locDestino, fecha)
    }
}

class MensajeDeTexto (numeroDestinoP: Long, cantCaracteresP: Integer, fechaP: Date)
    extends Comunicacion(numeroDestinoP, fechaP) with Duplicable[MensajeDeTexto]{	
    val CANTBLOQUECARACTERES: Integer = 140 //no deberia ser ##cero## aunque lo admite (y lo cobra)
    val PRECIOBLOQUECARACTERES: BigDecimal = 0.1
    var cantCaracteres: Integer = cantCaracteresP    
	def getCantCaracteres(): Integer = cantCaracteres	
	def setCantCaracteres(cantCaracteresP: Integer) = {
	    cantCaracteres = cantCaracteresP
	}
    
    def cantBloquesTexto() : Integer = {
        if(cantCaracteres < 1){
        	1
        }
        else{
        	var resto: Integer = cantCaracteres % CANTBLOQUECARACTERES    	
        	(if (resto > 0 ) 1 else 0) + ( (cantCaracteres - resto) / CANTBLOQUECARACTERES ) 
        }
    }
    
    override def precioComunicacion() : BigDecimal = {
      PRECIOBLOQUECARACTERES * BigDecimal.int2bigDecimal(cantBloquesTexto)
    }
    
    override def esComunicacionLarga(): Boolean = {
        this.cantCaracteres > 140
    }
    
    override def duplicate(): MensajeDeTexto = {
        new MensajeDeTexto(numeroDestino, cantCaracteres, fecha)
    }
}


